# 1.无参装饰器
def addStart(func):
    def wrapped():
        print("start")
        func()
    return wrapped


@addStart
def test1():
    print("hello world1")

test1()     # 无参装饰
print('-------------------------------------------------')




# 2.多参装饰器
def addStartArgs(func):
    def wrapped(*args, **kwargs):
        print("start")
        func(*args, **kwargs)
    return wrapped


@addStartArgs
def test2(arg1, arg2, arg3):
    print(arg1 + arg2 + arg3)

test2(1, 2, 3)
print('-------------------------------------------------')




# 3.返回参数装饰器
def addStartArgsRe(func):
    def wrapped(*args, **kwargs):
        print("start")
        return func(*args, **kwargs)  # 装饰器尽量都加上return, 能保证通用性, 有利无害, 顶多返回None
    return wrapped


@addStartArgsRe
def test3(arg1, arg2, arg3):
    return (arg1 + arg2 + arg3)

print(test3(2, 3, 4))
print('-------------------------------------------------')




# 4.装饰器带参数(本质是闭包) ----->装饰器的完整形态
def addStartArgsReDecargs(preArgs):
    def newfunc(func):
        def wrapped(*args, **kwargs):
            print("start")
            print(preArgs)               # 装饰器注解带入的参数
            # 装饰器尽量都加上return, 能保证通用性, 有利无害, 顶多返回None
            return func(*args, **kwargs)
        return wrapped
    return newfunc


@addStartArgsReDecargs('shuoGG')
def test4(arg1, arg2, arg3):
    return (arg1 + arg2 + arg3)

print(test4(3, 4, 5))
print('-------------------------------------------------')




# 5. 类装饰器
class AddStart(object):
    def __init__(self, func):
        self.__func = func          # func就是被装饰的函数

    def __call__(self):
        print('start')
        self.__func()               # 调用被装饰函数

@AddStart
def test5():
    print("----test5---")
test5()
print('-------------------------------------------------')
